#include "StdAfx.h"
#include "SpotLight.h"


CSpotLight::CSpotLight(void)
{
}


CSpotLight::~CSpotLight(void)
{
}

CColor4 CSpotLight::Shade(const CRay& vRay, const CVector3D& vPoint, const CVector3D& vNormal, const CGeometry& geometry, DATA_TYPE fTransparency) const
{
	CColor4 ambient = geometry.GetColor() * m_vColor * m_fAmbient;
	if (fTransparency < EPSILON)
	{
		return ambient;
	}

	CVector3D l = (GetPosition() - vPoint).Normalize();

	// cutoff
	DATA_TYPE fCosAngle = m_vDirection.Dot(-l);
	if (fCosAngle < m_fCutOffCosValue)
	{
		return ambient;
	}

	CVector3D vTemp = (l - vRay.GetDir());
	CVector3D h = vTemp / vTemp.GetLength();

	CColor4 diffuse = geometry.GetColor() * m_vColor * __max(0, vNormal.Dot(l));
	CColor4 specular = m_vColor * __max(0, powf(vNormal.Dot(h), geometry.GetMaterial().phongExponent));

	return ambient + fTransparency * (diffuse + specular) * powf(fCosAngle, m_fExponent);
}

void CSpotLight::Init(const CVector3D& vPosition, const CVector3D& vDirection, DATA_TYPE fAmbient, const CColor4& vColor, DATA_TYPE cutOff, DATA_TYPE exponent)
{
	__super::Init(vPosition, fAmbient, vColor);
	m_vDirection = vDirection;
	m_fCutOff = cutOff;
	m_fExponent = exponent;

	m_fCutOffCosValue = cosf(DEG2RAD(m_fCutOff));
}